home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
machack
/
Hacks97
/
BugsinMySerial.sit
/
Bugs in My Serial
/
Bugs in My Serial code
/
SerialMainBrian.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-27
|
9KB
|
451 lines
#include "patches.h"
#include <traps.h>
#include <lowmem.h>
#include "MacsBugSerialStuff.h"
#include <Gestalt.h>
//#include "NNumToString.h"
#include "ScreenMatrix.h"
static ScreenMatrix gScreen;
static asm long* GetOldDebugUtilStorage()
{
lea _oldDebugUtilStorage,a0
rts
_oldDebugUtilStorage:
dc.l 0x00000000
}
static asm long* GetCountStorage()
{
lea _countStorage,a0
rts
_countStorage:
dc.l 0x00000000
}
static asm long* GetValueStorage()
{
lea _valueStorage,a0
rts
_valueStorage:
dc.l 0x00000000
}
static asm long* GetA5Storage()
{
lea _a5Store,a0
rts
_a5Store:
dc.l 0x00000000
}
static Boolean KeyIsDown(
short theKeyCode)
{
KeyMap theKeys;
GetKeys( theKeys); /* Get state of each key */
/* Ordering of bits in a KeyMap is truly bizarre. A KeyMap is a */
/* 16-byte (128 bits) array where each bit specifies the start */
/* of a key (0 = up, 1 = down). We isolate the bit for the */
/* specified key code by first determining the byte position in */
/* the KeyMap and then the bit position within that byte. */
/* Key codes 0-7 are in the first byte (offset 0 from the */
/* start), codes 8-15 are in the second, etc. The BitTst() trap */
/* counts bits starting from the high-order bit of the byte. */
/* For example, for key code 58 (the option key), we look at */
/* the 8th byte (7 offset from the first byte) and the 5th bit */
/* within that byte. */
return( BitTst( ((char*) &theKeys) + theKeyCode / 8,
(long) 7 - (theKeyCode % 8) ) );
}
static Ptr GetScreenBase()
{
GDHandle h = LMGetMainDevice();
return h[0]->gdPMap[0]->baseAddr;
}
static const SInt32 kCharBlitOffset = 0x07B2;
typedef pascal void (*BlitCharProcPtr)(UInt8 character, PointPtr location);
BlitCharProcPtr gBlitCharProc = NULL;
const short kCharWidth = 6;
const short kCharHeight = 10;
void SMoveTo(short tY,short tX);
void SMoveTo(short tY,short tX)
{
Str255 message;
Str31 s;
message[0] = 1;
message[1] = 0x1B;
PLstrcat(message,"\p[");
NumToString(tY,s);
PLstrcat(message,s);
message[++message[0]] = ';';
NumToString(tX,s);
PLstrcat(message,s);
message[++message[0]] = ';';
message[++message[0]] = 'H';
SerialDriver_SendBytes(message+1,message[0]);
}
static void DrawCharAt(char inChar,short tX,short tY)
{
gScreen.DrawChar(tY,tX,inChar);
SMoveTo(tY,tX);
SerialDriver_SendBytes((unsigned char*)&inChar,1);
}
static void SendByte(UInt8 inByte,Point inPoint)
{
if(inPoint.v > 240) inPoint.v += 10;
if(inPoint.v > 400) inPoint.v += 10;
short tX = (inPoint.h/kCharWidth)+1;
short tY = (inPoint.v/kCharHeight)+1;
DrawCharAt(inByte,tX,tY);
}
const short kVerticalYStart = 1;
const short kVerticalYEnd = 49;
const short kVerticalXStart = 12;
const short kHorzXStart = 0;
static void DrawVerticalFrame(short x,short y)
{
DrawCharAt('|',x,y);
}
static void DrawHorzFrame(short x,short y);
static void DrawFrames()
{
for(short y = kVerticalYStart;y<= kVerticalYEnd;y++){
DrawVerticalFrame(kVerticalXStart,y);
}
/*
for(short x = kHorzXStart;x<=kHorzXEnd;x++){
DrawHorzFrame(x,kHorzYStart);
}
*/
}
static void SendClear()
{
Str32 s;
s[0] = 1; s[1] = 0x1B;
PLstrcat(s,"\p[2J");
SerialDriver_SendBytes(s+1,s[0]);
}
static Boolean ControlKeyQ()
{
KeyMap keys;
GetKeys(keys);
return ((keys[1] & 0x00000008) != 0);
}
static void RefreshScreen()
{
SendClear();
for(long row = 1;row<=ScreenMatrix::kHeight;row++){
Ptr theRow;
long theSize;
theRow = gScreen.GetIndRow(row,theSize);
SMoveTo(row,1);
SerialDriver_SendBytes((unsigned char*)theRow,theSize);
}
}
static void ReceiveData(long inMBA5)
{
gScreen.Sync();
if(SerialDriver_BytePresent()){
UInt8 theByte;
// Ptr p = GetScreenBase();
// *p = (*p)?0:0xFF;
if(SerialDriver_ReceiveByte(&theByte,10) == noErr){
if(theByte == '`'){
RefreshScreen();
}else{
long myA5 = SetA5(inMBA5);
PostEvent(keyDown,theByte);
PostEvent(keyUp,0);
SetA5(myA5);
}
}
}
}
/*
static BlitCharProcPtr FinalBlitChar(UInt8 character, PointPtr location)
{
#pragma unused(character, location)
long* theA5 = GetA5Storage();
SInt32 oldA5;
BlitCharProcPtr proc;
oldA5 = SetA5(*theA5);
proc = gBlitCharProc;
SetA5(oldA5);
return proc;
}
static asm pascal void BlitChar(UInt8 character, PointPtr location)
{
subq.l #4, sp
movem.l a0-a5/d0-d7, -(sp)
move.l 56+8(sp), -(sp)
move.w 56+16(sp), -(sp)
jsr FinalBlitChar
addq.l #6, sp
move.l a0, d0
beq NoCall
move.l a0, 56(sp)
movem.l (sp)+, a0-a5/d0-d7
rts
NoCall:
movem.l (sp)+, a0-a5/d0-d7
addq.l #4, sp
move.l (sp)+, a0
addq.l #6, sp
jmp (a0)
}
*/
struct RedirectCode
{
UInt16 jmp; // 0x4EF9
UInt32 addr;
UInt16 nop; // 0x4E71
} ;
struct DisplacedCode
{
UInt16 setA1; // 0x225F
UInt16 setA0; // 0x205F
UInt16 clrD1; // 0x4241
UInt16 setD1; // 0x121F
UInt16 jmp; // 0x4EF9
UInt32 addr;
} ;
static void _SetUpDisplacedAddr(UInt32* addrPtr)
{
long* theA5 = GetA5Storage();
SInt32 oldA5;
oldA5 = SetA5(*theA5);
*addrPtr = reinterpret_cast<UInt32>(gBlitCharProc);
(*addrPtr) += 8;
SetA5(oldA5);
}
static void SendCharToBlit(UInt8* character, PointPtr location)
{
#pragma unused(character, location)
long* theA5 = GetA5Storage();
SInt32 oldA5;
oldA5 = SetA5(*theA5);
SendByte(*character,*location);
// if (*character == '0')
// *character = '.';
SetA5(oldA5);
}
static void SetUpDisplacedAddr(void);
static asm pascal void BlitChar(UInt8 character, PointPtr location)
{
movem.l a0-a5/d0-d7, -(sp)
move.l 52+8(sp), -(sp)
// move.w 56+16(sp), -(sp)
pea 52+16(sp)
jsr SendCharToBlit
addq.l #8, sp
movem.l (sp)+, a0-a5/d0-d7
// begin displaced code
move.l (sp)+, a1
move.l (sp)+, a0
clr.w d1
move.b (a7)+, d1
// end displaced code
dc.w 0x4EF9
_addr: dc.l 0
entry static SetUpDisplacedAddr
pea _addr
jsr _SetUpDisplacedAddr
addq.l #4,sp
rts
}
static long Poll(short selector)
{
long continueQ = true;
long* theA5 = GetA5Storage();
SInt32 oldA5;
BlitCharProcPtr* proc;
oldA5 = SetA5(*theA5);
/*Point pt = { -1, -1 };
UInt8 tChar = 'Z';
SendCharToBlit(tChar, &pt);*/
switch(selector)
{
case 1:
SendClear();
DrawFrames();
proc = reinterpret_cast<BlitCharProcPtr*>(oldA5 - kCharBlitOffset);
gBlitCharProc = *proc;
SetUpDisplacedAddr();
RedirectCode* redir;
redir = reinterpret_cast<RedirectCode*>(*proc);
redir->jmp = 0x4EF9;
redir->addr = reinterpret_cast<UInt32>(BlitChar);
redir->nop = 0x4E71;
#if GENERATING68K
FlushCodeCacheRange(redir, sizeof(RedirectCode));
#else
MakeDataExecutable(redir, sizeof(RedirectCode));
#endif
/*
*proc = BlitChar;
*/
// Gestalt('S2S ', (long*)&proc);
// *proc = gBlitCharProc;
break;
case 2:
proc = reinterpret_cast<BlitCharProcPtr*>(oldA5 - kCharBlitOffset);
DisplacedCode* disp;
disp = reinterpret_cast<DisplacedCode*>(*proc);
disp->setA1 = 0x225F;
disp->setA0 = 0x205F;
disp->clrD1 = 0x4241;
disp->setD1 = 0x121F;
#if GENERATING68K
FlushCodeCacheRange(disp, sizeof(RedirectCode)); // sizeof(RedirectCode) is NOT a mistake
#else
MakeDataExecutable(disp, sizeof(RedirectCode)); // sizeof(RedirectCode) is NOT a mistake
#endif
/*
*proc = gBlitCharProc;
*/
gBlitCharProc = NULL;
break;
case 3:
ReceiveData(oldA5);
break;
}
SetA5(oldA5);
return continueQ;
}
static asm void newDebugUtil()
{
subq.l #4,a7 // reserve space for old trap address
move.l a0,-(a7) // save a0
movem.l a1-a5/d0-d7,-(a7) // save everything else
move.w d0,-(a7)
jsr Poll
addq.l #2,a7
tst.w d0
bne.s _Continue
movem.l (a7)+,a1-a5/d0-d7
move.l (a7)+,a0
addq.l #4,a7
rts
_Continue:
movem.l (a7)+,a1-a5/d0-d7 // restore registers
jsr GetOldDebugUtilStorage // get original trap address storage in a0
move.l (a0),a0 // get original trap address value into a0
move.l a0,4(a7) // stuff old trap onto stack
move.l (a7)+,a0 // restore original a0
rts // rts to jump to old trap.
}
void main()
{
SerialDriver_Open();
long* theA5 = GetA5Storage();
*theA5 = SetCurrentA5();
long* debugUtilStorage = GetOldDebugUtilStorage();
*debugUtilStorage = PatchTrap(_DebugUtil,(long)newDebugUtil);
(*((ProcPtr)0xFFFFFFFF))();
// SysBeep(1);
// SysBeep(1);
}